package com.crawler.system.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import lombok.Data;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * 爬虫规则实体类
 * 定义如何抓取和解析网页内容的规则配置
 * 
 * @author crawler-system
 */
@Data
@TableName(value = "crawler_rule", autoResultMap = true)
public class CrawlerRule {

    /**
     * 主键ID，自增长
     */
    @TableId(type = IdType.AUTO)
    private Long id;

    /**
     * 规则名称
     * 用于在UI中显示和识别规则
     */
    private String name;

    /**
     * 规则描述
     * 对规则的详细说明
     */
    private String description;

    /**
     * 目标网站
     * 规则适用的目标网站域名
     */
    private String targetSite;

    /**
     * 规则类型
     * HTML: 基于HTML解析的规则
     * JSON: 基于JSON解析的规则
     * XML: 基于XML解析的规则
     * MIXED: 混合类型规则
     * REGEX: 基于正则表达式的规则
     */
    private String ruleType;

    /**
     * URL模式
     * 匹配URL的正则表达式，确定规则适用的URL范围
     */
    private String urlPattern;

    /**
     * 负URL模式
     * 不匹配的URL正则表达式，用于排除特定URL
     */
    private String negativeUrlPattern;

    /**
     * 提取器配置
     * 定义从页面中提取数据的提取器列表，JSON格式
     * 例如：[
     *   {
     *     "name": "title",
     *     "type": "CSS",
     *     "selector": "h1.main-title",
     *     "attribute": "text",
     *     "required": true
     *   },
     *   {
     *     "name": "price",
     *     "type": "CSS",
     *     "selector": "span.price",
     *     "attribute": "text",
     *     "processor": "PRICE",
     *     "required": true
     *   }
     * ]
     */
    @TableField(typeHandler = JacksonTypeHandler.class)
    private List<Map<String, Object>> extractors;

    /**
     * 分页配置
     * 定义如何处理分页内容，JSON格式
     * 例如：{
     *   "enabled": true,
     *   "type": "NEXT_LINK",
     *   "selector": "a.next-page",
     *   "maxPages": 10,
     *   "pageParam": "page",
     *   "startPage": 1
     * }
     */
    @TableField(typeHandler = JacksonTypeHandler.class)
    private Map<String, Object> paginationConfig;

    /**
     * 请求头配置
     * 自定义请求头，JSON格式
     * 例如：{
     *   "User-Agent": "Mozilla/5.0...",
     *   "Referer": "https://example.com",
     *   "Cookie": "session=abc123"
     * }
     */
    @TableField(typeHandler = JacksonTypeHandler.class)
    private Map<String, String> headers;

    /**
     * 请求方法
     * GET, POST, PUT, DELETE等
     */
    private String method;

    /**
     * 请求体模板
     * 对于POST/PUT请求的请求体模板
     */
    private String requestBody;

    /**
     * 请求参数模板
     * URL查询参数模板，JSON格式
     */
    @TableField(typeHandler = JacksonTypeHandler.class)
    private Map<String, String> requestParams;

    /**
     * 请求间隔（毫秒）
     * 两次请求之间的最小间隔时间
     */
    private Integer requestInterval;

    /**
     * 请求超时（毫秒）
     * 请求的超时时间
     */
    private Integer requestTimeout;

    /**
     * 重试次数
     * 请求失败时的最大重试次数
     */
    private Integer retryCount;

    /**
     * 重试间隔（毫秒）
     * 重试之间的等待时间
     */
    private Integer retryInterval;

    /**
     * 链接提取器
     * 定义如何从页面中提取下一步要爬取的链接，JSON格式
     * 例如：{
     *   "enabled": true,
     *   "selectors": ["a.product-link", "a.category-link"],
     *   "attribute": "href",
     *   "patterns": ["product/\\d+", "category/\\w+"],
     *   "excludePatterns": ["login", "register"]
     * }
     */
    @TableField(typeHandler = JacksonTypeHandler.class)
    private Map<String, Object> linkExtractor;

    /**
     * 动态加载配置
     * 针对需要JavaScript渲染的页面的配置，JSON格式
     * 例如：{
     *   "enabled": true,
     *   "waitForSelector": ".content-loaded",
     *   "waitTime": 5000,
     *   "scrollToBottom": true,
     *   "scrollInterval": 1000,
     *   "clickSelectors": [".load-more"]
     * }
     */
    @TableField(typeHandler = JacksonTypeHandler.class)
    private Map<String, Object> dynamicLoadConfig;

    /**
     * JavaScript脚本
     * 在页面上下文中执行的自定义JavaScript脚本
     */
    private String javascript;

    /**
     * 代理配置
     * 代理设置，JSON格式
     * 例如：{
     *   "enabled": true,
     *   "rotationPolicy": "ROUND_ROBIN",
     *   "minResponseTime": 200,
     *   "maxFailCount": 3
     * }
     */
    @TableField(typeHandler = JacksonTypeHandler.class)
    private Map<String, Object> proxyConfig;

    /**
     * 验证码处理配置
     * 验证码识别和处理配置，JSON格式
     * 例如：{
     *   "enabled": true,
     *   "type": "IMAGE",
     *   "selector": "img.captcha",
     *   "inputSelector": "input[name=captcha]",
     *   "submitSelector": "button[type=submit]"
     * }
     */
    @TableField(typeHandler = JacksonTypeHandler.class)
    private Map<String, Object> captchaConfig;

    /**
     * 数据处理器
     * 数据处理配置，定义如何对提取的数据进行后处理，JSON格式
     * 例如：[
     *   {
     *     "field": "price",
     *     "processors": ["TRIM", "CURRENCY_TO_NUMBER"]
     *   },
     *   {
     *     "field": "description",
     *     "processors": ["HTML_TO_TEXT", "TRUNCATE:200"]
     *   }
     * ]
     */
    @TableField(typeHandler = JacksonTypeHandler.class)
    private List<Map<String, Object>> dataProcessors;

    /**
     * 是否启用
     * 规则是否可用于任务
     */
    private Boolean enabled;

    /**
     * 规则版本
     * 规则的版本号，用于处理规则更新
     */
    private String version;

    /**
     * 优先级
     * 当多个规则匹配同一URL时的优先级，数字越大优先级越高
     */
    private Integer priority;

    /**
     * 创建用户ID
     */
    private Long createdBy;

    /**
     * 创建时间
     */
    private LocalDateTime createTime;

    /**
     * 更新时间
     */
    private LocalDateTime updateTime;

    /**
     * 最后测试时间
     * 规则最后一次测试的时间
     */
    private LocalDateTime lastTestTime;

    /**
     * 测试结果
     * 规则最后一次测试的结果，SUCCESS或FAILED
     */
    private String testResult;

    /**
     * 测试说明
     * 规则测试的详细结果信息
     */
    private String testDetails;

    /**
     * 标签
     * 用于分类和搜索规则的标签，逗号分隔
     */
    private String tags;

    /**
     * 是否为系统规则
     * 系统预定义的规则，用户不可删除
     */
    private Boolean isSystem;

    /**
     * 选择器类型(CSS, XPATH, REGEX)
     */
    private String selectorType;
    
    /**
     * 选择器
     */
    private String selector;
    
    /**
     * 提取类型 (TEXT, HTML, ATTRIBUTE, LIST)
     */
    private String extractType;
    
    /**
     * 属性名称
     */
    private String attributeName;
    
    /**
     * 字段名称
     */
    private String fieldName;
    
    /**
     * 是否必需
     */
    private Boolean required;
} 
